﻿using Core.DataAccess.Model.Project.Queue;
using Core.Framework.Model.WebSockets;
using Core.Framework.Redis.Queue_Helper;
using Core.Framework.Util;
using Core.IBusiness.ISocketModule;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Core.Business.SocketModule
{
    public class SocketGroup : ISocketGroup
    {
        public Tuple<ProjectModuleGroupUser, string, bool> AddGroupUser(ProjectModuleGroupUser model)
        {
            using (var context = new ProjectSocketContext())
            {

                var tuple = model.IsValid(IsValidEnum.reg);

                if (!tuple.Item1)
                    return new Tuple<ProjectModuleGroupUser, string, bool>(model, tuple.Item2, false);
                var userid = model.UserId.ToInt();
                var userInfo =
                    context.ProjectModuleUser.Where(a => a.Id == userid && a.ProjectToken == model.ProjectToken).FirstOrDefault();

                if (userInfo != null && userInfo?.Id > 0)
                {
                    context.ProjectModuleGroupUser.Add(model);
                    context.SaveChanges();
                    this.UpdateUserSubscriptionByAddGroup(userInfo.Token, model.ProjectToken, model.GroupKey);
                    return new Tuple<ProjectModuleGroupUser, string, bool>(model, "加入群组成功", true);
                }
                else {
                    return new Tuple<ProjectModuleGroupUser, string, bool>(model, "用户不存在", false);
                }
            };
        }

        public Tuple<ProjectModuleGroup, string, bool> Create(ProjectModuleGroup model)
        {
            using (var context = new ProjectSocketContext())
            {

                var tuple = model.IsValid(IsValidEnum.reg);

                if (!tuple.Item1)
                    return new Tuple<ProjectModuleGroup, string, bool>(model, tuple.Item2, false);

                context.ProjectModuleGroup.Add(model);

                context.SaveChanges();

                return new Tuple<ProjectModuleGroup, string, bool>(model, "创建成功", true);
            }

            ;
        }

        public Tuple<ProjectModuleGroup, bool> Delete(int id, string userKey, string projectToken)
        {
            using (var context = new ProjectSocketContext())
            {

                var model = context
                    .ProjectModuleGroup
                    .Where(a => a.Id == id && a.UserId == userKey && a.ProjectToken == projectToken)
                    .FirstOrDefault();
                if (model?.Id > 0)
                {
                    context.ProjectModuleGroup.Remove(model);
                    context.SaveChanges();
                    return new Tuple<ProjectModuleGroup, bool>(model, true);
                }

                return new Tuple<ProjectModuleGroup, bool>(model, false);

            }

            ;
        }

        public Tuple<ProjectModuleGroup, bool> GetById(int id, string projectToken)
        {
            using (var context = new ProjectSocketContext())
            {

                var model = context
                    .ProjectModuleGroup
                    .Where(a => a.Id == id && projectToken == a.ProjectToken)
                    .FirstOrDefault();
                if (model?.Id > 0)
                    return new Tuple<ProjectModuleGroup, bool>(model, true);

                return new Tuple<ProjectModuleGroup, bool>(model, false);

            }

            ;
        }

        public Tuple<List<ProjectModuleGroup>, bool> GetByUserKey(string userKey, string projectToken)
        {
            using (var context = new ProjectSocketContext())
            {

                var groupKeys = context.ProjectModuleGroupUser
                    .Where(a => a.UserId == userKey && a.ProjectToken == projectToken)
                    .GroupBy(a => a.GroupKey)
                    .Select(a => a.Key).ToList();

                if (groupKeys?.Count > 0)
                {
                    var list = context
                            .ProjectModuleGroup
                            .Where(a => groupKeys.Contains(a.Id))
                            .ToList();

                    return new Tuple<List<ProjectModuleGroup>, bool>(list, true);
                }

                return new Tuple<List<ProjectModuleGroup>, bool>(null, true);
            }

            ;
        }

        public Tuple<List<int>, bool> GetGroupsByUserKey(string userKey, string projectToken)
        {
            using (var context = new ProjectSocketContext())
            {

               var groupKeys = context.ProjectModuleGroupUser
                    .Where(a => a.UserId == userKey && a.ProjectToken == projectToken)
                    .GroupBy(a => a.GroupKey)
                    .Select(a => a.Key).ToList();

                if (groupKeys?.Count > 0)
                {
                    var list = context
                        .ProjectModuleGroup
                        .Where(a => groupKeys.Contains(a.Id))
                        .Select(a => a.Id)
                        .ToList();

                    return new Tuple<List<int>, bool>(list, true);
                }

                return new Tuple<List<int>, bool>(null, true);
            }

            ;
        }

        public Tuple<List<ProjectModuleGroupUser>, bool> GetGroupUsersByGroupKey(int id, string projectToken)
        {
            using (var context = new ProjectSocketContext())
            {

                var list = context
                    .ProjectModuleGroupUser
                    .Where(a => a.GroupKey == id && a.ProjectToken == projectToken)
                    .ToList();

                return new Tuple<List<ProjectModuleGroupUser>, bool>(list, true);
            }

            ;
        }

        public Tuple<ProjectModuleGroup, string, bool> Update(ProjectModuleGroup model)
        {
            using (var context = new ProjectSocketContext())
            {

                var tuple = model.IsValid(IsValidEnum.update);

                if (!tuple.Item1)
                    return new Tuple<ProjectModuleGroup, string, bool>(model, tuple.Item2, false);

                context.ProjectModuleGroup.Update(model);
                context.SaveChanges();

                return new Tuple<ProjectModuleGroup, string, bool>(model, "修改成功", true);
            }

            ;
        }

        public Tuple<ProjectModuleGroupUser, string, bool> UpdateGroupUser(ProjectModuleGroupUser model)
        {
            using (var context = new ProjectSocketContext())
            {

                var tuple = model.IsValid(IsValidEnum.update);

                if (!tuple.Item1)
                    return new Tuple<ProjectModuleGroupUser, string, bool>(model, tuple.Item2, false);

                context.ProjectModuleGroupUser.Update(model);
                context.SaveChanges();

                return new Tuple<ProjectModuleGroupUser, string, bool>(model, "修改成功", true);
            }

            ;
        }

        #region Common

        /// <summary>
        /// 创建分组 调整订阅渠道
        /// </summary>
        /// <param name="usertoken"></param>
        /// <param name="projecttoken"></param>
        /// <param name="paras"></param>
        private void UpdateUserSubscriptionByAddGroup(string usertoken, string projecttoken, int group)
        {
            // 读出WS缓存
            var wsValue = (string)RedisQueueHelper.HashGet(RedisQueueHelperParameter.WebSocketByToken, usertoken);

            // 判断是否登录WS会话
            if (!string.IsNullOrWhiteSpace(wsValue))
            {
                ClientInfo client = wsValue.TryToEntity<ClientInfo>();

                WebSocketApplication.ClientSubscribe(client, $"group_{group}");

                RedisQueueHelper.HashSet(RedisQueueHelperParameter.WebSocketByToken, usertoken, client.TryToJson());
            }

        }

        #endregion
    }
}
